package elitequant.strategy.mystrategy;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import elitequant.data.BarEvent;
import elitequant.event.EventsEngine;
import elitequant.order.OrderEvent;
import elitequant.order.OrderType;
import elitequant.strategy.StrategyBase;

/**
 * classical MovingAverageCrossStrategy, golden cross
 * 
 */
public class MovingAverageCrossStrategy extends StrategyBase {
	
    private int shortWindow;
    
    private int longWindow;
    
    private boolean invested;
    
    private List<BigDecimal> prices;
    
    
    public MovingAverageCrossStrategy(String[] symbols, EventsEngine eventsEngine) {
		this(symbols, eventsEngine, 50, 200);
	}
    
    public MovingAverageCrossStrategy(String[] symbols, EventsEngine eventsEngine, int shortWindow, int longWindow) {
		super(symbols, eventsEngine);
		this.shortWindow = shortWindow;
		this.longWindow = longWindow;
		prices = new ArrayList<BigDecimal>();
	}

	@Override
	public void onBar(BarEvent barEvent) {
        String symbol = symbols[0];
       // Only applies SMA to first ticker
        if(!symbol.equals(barEvent.fullSymbol)){
        	return;
        }
            
        // Add latest adjusted closing price to price list
        prices.add(barEvent.adjClosePrice);

        // wait for enough bars
        if(prices.size() >= longWindow){
            // Calculate the simple moving averages
            BigDecimal shortSMA = mean(prices.subList(prices.size() - shortWindow, prices.size()));
            BigDecimal longSMA = mean(prices.subList(prices.size() - longWindow, prices.size()));
            // Trading signals based on moving average cross
            if(shortSMA.compareTo(longSMA) > 0 && !invested){
                System.out.println(String.format("Long: %tc, short_sma %.2f, long_sma %.2f", barEvent.barEndTime(), shortSMA, longSMA ));
                OrderEvent o = new OrderEvent();
                o.fullSymbol = symbol;
                o.orderType = OrderType.MARKET;
                o.size = 100;
                placeOrder(o);
                invested = true;
            }
            else if(shortSMA.compareTo(longSMA) < 0 && invested){
                System.out.println(String.format("Short: %tc, short_sma %.2f, long_sma %.2f", barEvent.barEndTime(), shortSMA, longSMA ));
                OrderEvent o = new OrderEvent();
                o.fullSymbol = symbol;
                o.orderType = OrderType.MARKET;
                o.size = -100;
                placeOrder(o);
                invested = false;
            }

        }
	}
        
    private static BigDecimal mean(List<BigDecimal> list){
        BigDecimal sum = new BigDecimal(0);
    	for(BigDecimal value: list){
    	    sum = sum.add(value);
    	}
    	return sum.divide(new BigDecimal(list.size()));
    }


}
